PURE functional. NO side effects. Everything returns, should be deterministic.
Life isn't deterministic. This is why people think it's not useful.
Drawn from, return (opposites)
main :: IO ()
main = do
putStrLn "quit the program? y/n"
ans <- getLine
if ans /= "y" then do
putStrLn "not quitting"
main
else return ()
-- or
when (ans /= "y") $ do
putStrLn "not quitting"
mainWe'll have:
Next slides are from this excellent tutorial.
Applying functions now depends on context:
data Maybe a = Just a | Nothingfmap (+3) (Just 2)Functor is a typeclass:
Functor is just a data type that defines fmap for itself:
So we can:
instance Functor Maybe where
fmap func (Just val) = Just (func val)
fmap func Nothing = Nothing
fmap (+3) (Just 2)Behind the scenes of fmap (+3) (Just 2) we get:
Try to apply (+3) to Nothing and you get:
ghci>fmap (+3) Nothing
NothingNil is often used as bottom as well as status. In Haskell we still have bottom: undefined.
Because bottom subsumes non-termination, the function
isUndefinedwould have to solve the halting problem and thus cannot exist.
post = Post.find_by_id(1)
if post
return post.title
else
return nil
endfmap (getPostTitle) (findPost 1)
--- or with infix
getPostTitle <$> (findPost 1)Because:
instance Functor [] where
fmap = mapNormal:
fmap (+3) (*2)instance Functor ((->) r) where
fmap f g = f . gAs a functor, it's function composition! As a monad:
instance Applicative ((->) r) where
-- pure :: a -> r -> a
pure = const
-- (<*>) :: (r -> a -> b) -> (r -> a) -> r -> b
(<*>) g f r = g r (f r)
instance Monad ((->) r) where
-- return :: a -> r -> a
return = const
-- (>>=) :: (r -> a) -> (a -> r -> b) -> r -> b
(>>=) x y z = y (x z) zBoth are wrapped in contexts!
Just 2
Just (+3)
ghci>Just (+2) <*> Just 5From base:
instance Functor [] where
fmap = map
instance Applicative [] where
pure x = [x]
fs <*> xs = [f x | f <- fs, x <- xs]
xs *> ys = [y | _ <- xs, y <- ys]
instance Monad [] where
xs >>= f = [y | x <- xs, y <- f x]
(>>) = (*>)
return x = [x]
fail _ = []-- So... what is this?
[(*2),(+3)] <*> [1, 2, 3]Apply function that takes 2 args to 2 wrapped values!
ghci>(+) <$> (Just 5)
Just (+5)
ghci>Just (+5) <$> Just 4
ERRRRR-- Applicative
ghci>(+) <$> Just 5 <*> Just 4
Just 9
ghci>liftA2 (*) (Just 5) (Just 3)
Just 15half x = if even x
then Just (x `div` 2)
else NothingPlunger is >>=
> Just 3 >>= half
Nothing
> Just 4 >>= half
Just 2
> Nothing >>= half
Nothinginstance Monad Maybe where
Nothing >>= func = Nothing
Just val >>= func = func val